package com.hucsmn.examsystem.common;

import com.hucsmn.examsystem.util.BuildStrings;

import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Objects;

/**
 * 用户信息。
 */
public class User implements Serializable, Cloneable {
    private static final long serialVersionUID = -1083724037095094993L;

    // 密码加密常量。

    private static final byte[] CRYPT_PREFIX = new byte[]{'S', 'A', 'L', 'T', '['};
    private static final byte[] CRYPT_SUFFIX = new byte[]{']', 'E', 'N', 'D'};

    // 编号、用户名、加密后的密码。

    private int id;
    private String name;
    private String pass;

    // 构造函数。

    public User(int id, String name, String pass) {
        if (id < 0) {
            throw new IllegalArgumentException("negative user id");
        }
        this.id = id;
        setName(name);
        setPass(pass);
    }

    // getter 和 setter。

    public int getId() {
        return id;
    }

    public void setId(int id) {
        if (id < 0) {
            throw new IllegalArgumentException("negative user id");
        }
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        if (name == null) {
            throw new NullPointerException();
        }
        if (name.isEmpty()) {
            throw new IllegalArgumentException();
        }
        this.name = name;
    }

    public String getPass() {
        return pass;
    }

    public void setPass(String pass) {
        if (pass == null) {
            throw new NullPointerException();
        }
        if (pass.isEmpty()) {
            throw new IllegalArgumentException();
        }
        this.pass = crypt(pass);
    }

    // 工具方法。

    private String crypt(String pass) {
        try {
            MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
            sha256.update(CRYPT_PREFIX);
            sha256.update(pass.getBytes(StandardCharsets.UTF_8));
            sha256.update(CRYPT_SUFFIX);
            return BuildStrings.bytesToString(sha256.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return name.equals(user.name) && pass.equals(user.pass);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, pass);
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("User{");
        sb.append("id='").append(id).append('\'');
        sb.append(", name='").append(name).append('\'');
        sb.append(", crypt-pass=").append(pass);
        sb.append('}');
        return sb.toString();
    }
}
